/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.entityimpl;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.operation.BizAction;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.BefDataImplGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.BefRtEntityGenCtx;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.cacheinfo.GetCacheInfoFieldGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.cacheinfo.GetCacheInfoMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.BefCreateAfterCreateDtmAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.BefCreateAfterModifyDtmAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.BefCreateAfterModifyValAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.BefCreateBeforeSaveDtmAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.BefCreateBeforeSaveValAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.CreateAfterLoadingDtmAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.CreateAfterSaveValAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.createdtmassmethodgen.CreateOnCancelDtmAssMethodGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.method.CreateChildAccessorGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.method.CreateChildEntityDataGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.method.CreateEntityDataGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.method.GetChildBEEntityGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.entitygen.tcc.CreateTccAssemblerGenerator;
import com.inspur.edp.caf.generator.BaseGenerator;
import com.inspur.edp.caf.generator.field.FieldGenerator;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.property.ClassPropertyGenerator;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.coreGenerator.base.accessorgen.ReadonlyRootAcsGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.accessorgen.RootAcsGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.dualaccgen.RootDualAcsGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.DataTypeImpContext;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.EntityDataImplGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.EntityGeneratorContext;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.EntityImplGenerator;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import java.util.ArrayList;
import org.hibernate.annotations.Parent;

/**
 * BE节点生成器基类
 */
public abstract class BefEntityImplGenerator extends EntityImplGenerator {

  public BefRtEntityGenCtx parContext;
  protected GspBizEntityObject node;

  public BefEntityImplGenerator(BefRtEntityGenCtx parContext, GspBizEntityObject node) {
    super(parContext, node);
    this.parContext = parContext;
    this.node = node;
  }

  protected BefEntityImplGenCtx getBefEntityImplContext() {
    return (BefEntityImplGenCtx) super.getContext();
  }

  @Override
  protected DataTypeImpContext getDataTypeImpContext() {
    BefEntityImplGenCtx ctx = new BefEntityImplGenCtx(parContext){{setDataType(node);}};
    return ctx;
  }

  @Override
  protected void addExtendMethodGenerator(ArrayList<ClassMethodGenerator> generators) {
    super.addExtendMethodGenerator(generators);
    MediateType entityType = null;
    generators
        .add(new CreateChildEntityDataGenerator(getBefEntityImplContext(), node));
    generators
        .add(new CreateEntityDataGenerator(entityType, getBefEntityImplContext(), node.getCode(), node));
    generators
        .add(new GetChildBEEntityGenerator(getBefEntityImplContext(), node));
    generators.add(new CreateChildAccessorGenerator(
        getBefEntityImplContext(), childEntitiesAttribute));

    for (BizOperation operation : node.getBizActions()) {
      BizAction action = (BizAction) operation;
      if (action.getIsRef()
          || action instanceof com.inspur.edp.bef.bizentity.operation.internalbeaction.IInternalBEAction) {
        continue;
      }
      generators.add(new BEImplMethodGenerator(getBefEntityImplContext(), action, node));
    }

    if(CreateTccAssemblerGenerator.needGenerate(node))
      generators.add(new CreateTccAssemblerGenerator(getBefEntityImplContext(), node));
  }

  @Override
  protected EntityDataImplGenerator getDataGenerator(MediateType baseType) {
    return new BefDataImplGenerator(ParentContext, node, baseType);
  }

  @Override
  protected void addAccessorGenerators(ArrayList<BaseGenerator> gens,
      EntityGeneratorContext entityContext, String node, MediateType baseDataType) {
    RootDualAcsGenerator rootAsscGen = new RootDualAcsGenerator(entityContext, this.node, baseDataType);
    gens.add(rootAsscGen);
  }

  @Override
  protected EntityImplGenerator getChildEntityImplGenerator(IGspCommonObject childNode) {
    return new ChildEntityImplGenerator(parContext, (GspBizEntityObject) childNode);
  }

  @Override
  protected void addExtendDtmAssMethodGenerator(ArrayList<ClassMethodGenerator> methodGens) {
    methodGens
        .add(new CreateAfterLoadingDtmAssMethodGenerator(getBefEntityImplContext(), node.getCode()));
    methodGens.add(new CreateOnCancelDtmAssMethodGenerator(getBefEntityImplContext(), node.getCode()));
    methodGens.add(new CreateAfterSaveValAssMethodGenerator(getBefEntityImplContext(), node.getCode()));
  }

  @Override
  protected ArrayList<ClassPropertyGenerator> createPropertyGenerators() {

    ArrayList<ClassPropertyGenerator> result = super.createPropertyGenerators();
    if (result == null) {
      result = new ArrayList<ClassPropertyGenerator>();
    }
    if (node.getIsRootNode()) {
      result.add(new RootEntityNodeCodePropGenerator(getBefEntityImplContext()));
    }
    return result;
  }

  //region dtm/val Assembler

  @Override
  protected ClassMethodGenerator getCreateAfterModifyDtmAssMethodGenerator() {
    return new BefCreateAfterModifyDtmAssMethodGenerator(getBefEntityImplContext(), node.getCode());
  }

  @Override
  protected ClassMethodGenerator getCreateAfterCreateDtmAssMethodGenerator() {
    return new BefCreateAfterCreateDtmAssMethodGenerator(getBefEntityImplContext(), node.getCode());
  }

  @Override
  protected ClassMethodGenerator getCreateBeforeSaveDtmAssMethodGenerator() {
    return new BefCreateBeforeSaveDtmAssMethodGenerator(getBefEntityImplContext(), node.getCode());
  }

  @Override
  protected ClassMethodGenerator getCreateAfterModifyValAssMethodGenerator() {
    return new BefCreateAfterModifyValAssMethodGenerator(getBefEntityImplContext(), node.getCode());
  }

  @Override
  protected ClassMethodGenerator getCreateBeforeSaveValAssMethodGenerator() {
    return new BefCreateBeforeSaveValAssMethodGenerator(getBefEntityImplContext(), node.getCode());
  }
  //endregion

  //region cacheInfo

  @Override
  protected ClassMethodGenerator getDataTypeCacheInfoMethodGenerator() {
    return new GetCacheInfoMethodGenerator();
  }

  @Override
  protected FieldGenerator getDataTypeCacheInfoFieldGenerator() {
    return new GetCacheInfoFieldGenerator();
  }

  //endregion

//  @Override
//  protected ArrayList<BaseGenerator> createClassExtendChildGenrators() {
//    ArrayList<BaseGenerator> baseExtendGens = super.createClassExtendChildGenrators();
//    if (baseExtendGens == null) {
//      baseExtendGens = new ArrayList();
//    }
//    baseExtendGens.add(new BeDtmsGenerator(getBefEntityImplContext()));
//    baseExtendGens.add(new BeValidationsGenerator(getBefEntityImplContext()));
//    return baseExtendGens;
//  }
}
